#ifndef _AtomicWrapper_H__
#define _AtomicWrapper_H__

#include <signal.h>
#include "Common.h"
#include "SharedPtr.h"

    template <class T> class AtomicObject {

        public:

        AtomicObject (const T &initial)
            : mField(initial)
        {   }

        AtomicObject (const AtomicObject<T> &cousin)
            : mField(cousin.get())
        {   }

        AtomicObject ()
        {   }

        void operator= (const AtomicObject<T> &cousin)
        {
            set(cousin.get());
        }

        T get (void) const
        {
            WGS_LOCK_AUTO_MUTEX
            return mField;
        }

        void set (const T &v)
        {
            WGS_LOCK_AUTO_MUTEX
            mField = v;
        }

        bool cas (const T &old, const T &nu)
        {
            WGS_LOCK_AUTO_MUTEX
            if (mField != old) return false;
            mField = nu;
            return true;
        }

        T operator++ (void)
        {
            WGS_LOCK_AUTO_MUTEX
            return ++mField;
        }

        T operator++ (int)
        {
            WGS_LOCK_AUTO_MUTEX
            return mField++;
        }

        T operator-- (int)
        {
            WGS_LOCK_AUTO_MUTEX
            return mField--;
        }

        protected:

        WGS_AUTO_MUTEX

        volatile T mField;

    };

    template<class T> class AtomicScalar
    {

        public:

        AtomicScalar (const T &initial)
            : mField(initial)
        {   }

        AtomicScalar (const AtomicScalar<T> &cousin)
            : mField(cousin.mField)
        {   }

        AtomicScalar () 
        {   }

        void operator= (const AtomicScalar<T> &cousin)
        {
            mField = cousin.mField;
        }

        T get (void) const
        {
            return mField;
        }

        void set (const T &v)
        {
            mField = v; 
        }   

        bool cas (const T &old, const T &nu)
        {
            return __sync_bool_compare_and_swap (&mField, old, nu);
        }
            
        T operator++ (void)
        {
            __sync_add_and_fetch (&mField, 1);
        }
            
        T operator-- (void)
        {
            __sync_add_and_fetch (&mField, -1);
        }

        T operator++ (int)
        {
            __sync_fetch_and_add (&mField, 1);
        }
            
        T operator-- (int)
        {
            __sync_fetch_and_add (&mField, -1);
        }


        volatile T mField;

    };



#endif

